数塔问题是一个很经典的问题,它是每个人学习动态规划的入门题,数塔问题也是理解和分析动态规划的经典,它里面所反映出现的性质也是相对于其他动态规划题目更明显,最优子结构和无后效性在数塔里面反映的很明显,如果一个数塔你是从后面往上计算的话,你从下面每一层往上计算的结果都是最优的,下一次你做出的决策是在上面最优的结果上面进行的。
做dp题目切记当前最优不一定是全局最优,比如最后一个例子中你如果只是记录两个脚的每次走的路径的话那么你只是做到当前最优,那么这样的话也一定是不对的,还有今天一个学长dp题目说道,做dp题目首先是列状态,怎么列状态呢,就是看看那些因素对结果产生了影响,比如位置、时间。。。
首先,经典是数塔问题大家都知道吧,从下往上dp每一步只能从下面的左边或者右边走过来选择一个最小的,最后dp到顶端也是就是最大的或者最小的一个值,当然从上往下dp也是可以的。对于当前的每一个点,也是只能从上边的左边或者右边选择一个最大的。最后在最后一行数中求一个最大值既为结果。
状态转移方程v[i-1][j]+=v[i][j]>v[i][j+1]?v[i][j]:v[i][j+1];
从下往上求解代码:比较简单
#include <stdio.h>
int v[100][100];
int main()
{
int n,i,j;
while(~scanf("%d",&n))
{
for(i=0;i<n;i++)
{
for(j=0;j<=i;j++)
scanf("%d",&v[i][j]);
}
for(i=n;--i;){
for(j=0;j<i;++j){
v[i-1][j]+=v[i][j]>v[i][j+1]?v[i][j]:v[i][j+1];
}
}
printf("%d\n",v[0][0]);
}
return 0;
}
从上往下求解,比较复杂一点。
#include <iostream>
using namespace std;
intMax(int a,int b)
{
return a>b?a:b;
}
int main()
{
int a[110][110];
int n;
cin>>n;
for(int i=1;